﻿namespace Ann
{
  using System;
  using System.Collections;
  using System.Collections.Generic;
  using System.Text;
  using Reals.Existence;
  using Reals.Parellel;

  /// <summary>
  /// AnnCell 人工神经元网络中的细胞，即神经元本身。
  /// </summary>
  /// <remarks>
  /// 冲动过程：
  /// 
  /// 膜前神经元达到冲动电位。
  /// 电位波动可以在膜上以电容方式传递，直到达到轴突末梢。
  /// 
  /// 当这个电势波动来到轴突的末梢，
  /// 轴突末梢的膜上一些特化的门会打开，将神经递质放出。
  /// 
  /// 突触的后膜，也就是树突的前膜，对于递质十分的敏感。
  /// 递质可以将树突前膜的某些通道打开，使得一些离子流入。
  /// 这些离子，是在外环境普遍存在的钠离子。
  /// 
  /// 当钠离子从这些刚刚打开的通道流入，细胞的电位平衡就开始被破坏了。
  /// 
  /// 内部的电位就一直的升高，直到某一刻。
  /// 这一刻，由于电位足够的高(但还是内负外正)，
  /// 几乎所有的门都自动的打开了，钠离子如雪崩一般流入，
  /// 电位开始急剧的升高，最终达到内正外负的程度。
  /// 
  /// 	这个电位已经足以使得所有的钾通道打开了。
  ///     细胞含有大量的钾离子，打开钾的通道，就使得钾离子按照浓度梯度大量的外流，
  ///     在短短的几个毫秒的时间，几乎倾泻一空。而钾的失去又使得细胞的膜电位瞬间的降低。
  ///     细胞经历了一个大起大落的劫数。
  /// 此后，细胞使用Na,K泵机制将细胞的离子浓度恢复原来的样子，等待下一此输入。
  /// 
  /// 
  /// 关于时空叠加和编码：
  /// 
  /// 这毕竟是神经模拟，不必和神经完全一致。
  /// 我们可以用自己的想法来优化神经编码。
  /// 
  /// 比如，如果神经系统需要多个神经元来保证
  /// 输入的顺序得到检查，那么我们就可以用单个
  /// 神经元上的输入端到达的顺序来模拟。
  /// </remarks>
  public partial class AnnNeuron
  {
    #region Statics
    #region Shortcuts
    public static AnnNeuron of(AnnCellCluster cluster)
    {
      return new AnnNeuron(cluster);
    }
    #endregion
    #region Helpers
    #endregion
    #endregion
    #region Fields
    /// <summary>
    /// 所有的神经输出
    /// </summary>
    protected List<AnnExporter> exporters = null;
    /// <summary>
    /// 所有的神经输入
    /// </summary>
    protected List<AnnImporter> importers = null;
    /// <summary>
    /// 神经元所在的脑结构
    /// </summary>
    protected AnnBrain brain = null;
    #endregion
    #region Properties
    /// <summary>
    /// 获取神经输出
    /// </summary>
    protected virtual List<AnnExporter> Exporters
    {
      get
      {
        return this.exporters == null ?
          this.exporters = new List<AnnExporter>() :
          this.exporters;
      }
    }
    /// <summary>
    /// 获取神经输入
    /// </summary>
    protected virtual List<AnnImporter> Importers
    {
      get
      {
        return this.importers == null ?
          this.importers = new List<AnnImporter>() :
          this.importers;
      }
    }
    #endregion
    #region Constructors
    public AnnNeuron(AnnCellCluster cluster):base(cluster)
    {
    
    }
    #endregion
    #region Methods
    #region Publics
    /// <summary>
    /// 分裂细胞。
    /// </summary>
    /// <remarks>
    /// 在细胞球分裂维数的时候，
    /// 细胞会收到这个消息，
    /// 细胞自身决定是否分裂。
    /// 一个细胞的分裂与否，往往决定了
    /// 它的最终角色。如果一个细胞选择
    /// 不分裂，那么它很可能成为联系
    /// 同一维数上两个或者多个不同区域
    /// 的枢纽。
    /// </remarks>
    public virtual AnnNeuron Split(AnnSphere sphare)
    {
      return this;
    }
    protected virtual AnnImporter GenerateImporter()
    {
      return this.AddImporter(AnnImporter.of(this));
    }
    protected virtual AnnExporter GenerateExporter()
    {
      return this.AddExporter(AnnExporter.of(this));
    }
    #endregion
    #region Internals
    #region Initialize
    protected override void Initialize()
    {
      base.Initialize();
      this.GenerateImporter();
      this.GenerateExporter();
    }
    #endregion
    #region Linkers
    protected virtual AnnImporter AddImporter(AnnImporter importer)
    {
      if (importer != null)
      {
        this.Importers.Add(importer);
      }
      return importer;
    }
    protected virtual AnnImporter RemoveImporter(AnnImporter importer)
    {
      if (importer != null && this.importers!=null)
      {
        this.Importers.Remove(importer);
      }
      return importer;
    }
    protected virtual AnnExporter AddExporter(AnnExporter exporter)
    {
      if (exporter != null)
      {
        this.Exporters.Add(exporter);
      }
      return exporter;
    }
    protected virtual AnnExporter RemoveExporter(AnnExporter exporter)
    {
      if (exporter != null && this.exporters !=null)
      {
        this.Exporters.Remove(exporter);
      }
      return exporter;
    }
    #endregion
    #region Activities
    /// <summary>
    /// 内部活动等时面方法。
    /// </summary>
    /// <returns></returns>
    protected override bool InternalActivity()
    {
      return base.InternalActivity();
    }    
    /// <summary>
    /// 交互活动等时面方法。
    /// </summary>
    protected override bool InteractActivity()
    {
      return base.InteractActivity();
    }
    /// <summary>
    /// 当到达电位峰值的时候发生。
    /// </summary>
    protected override double OnPeakPontential(double potential)
    {
      //以雪崩电位发送电位信号。
      return base.OnPeakPontential(this.DeliveryPotential(potential));
    }
    #endregion
    #region Ions
    /// <summary>
    /// 传导电势波动。
    /// </summary>
    protected virtual double DeliveryPotential(double potential)
    {
      foreach (AnnExporter exporter in this.Exporters)
      {
        if (exporter != null)
        {
          exporter.Pulse(potential);
        }
      }
      return potential;
    }
    /// <summary>
    /// 打开一定数量的通道（Na＋）通道，以增加离子通透性。
    /// </summary>
    protected virtual ulong OpenChannels(ulong channels)
    {
      return Utils.Increase(ref this.OpenNatriumChannelQuantity, channels);
    }
    /// <summary>
    /// 关闭一定数量的通道（Na＋）通道，以减少离子通透性。
    /// </summary>
    protected virtual ulong CloseChannels(ulong channels)
    {
      return Utils.Decrease(ref this.OpenNatriumChannelQuantity, channels);
    }
    #endregion
    #endregion
    #endregion
  }
}